﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using LoveMusic.Helpers;

namespace Dal
{
    public partial class ModelDataContext
    {
        partial void OnCreated()
        {
            //Put your desired timeout here.
            this.CommandTimeout = 8;

            //If you do not want to hard code it, then take it 
            //from Application Settings / AppSettings
            //this.CommandTimeout = Settings.Default.CommandTimeout;
        }

        /// <summary>
        /// The same as regular with 4 votes only
        /// </summary>
        /// <param name="songTitle"></param>
        /// <param name="artistName"></param>
        /// <param name="categoryId"></param>
        /// <param name="description"></param>
        /// <param name="tags"></param>
        /// <param name="fileUrl"></param>
        /// <param name="encodingCode"></param>
        /// <param name="videoID"></param>
        /// <param name="imageURL"></param>
        /// <param name="hasImage"></param>
        /// <param name="userId"></param>
        /// <param name="youTubeDescription"></param>
        /// <returns></returns>
        public int SubmitStoryBot(string songTitle, string artistName, int categoryId, string description, string tags, List<String> fileUrl, string videoID, Guid userId, string youTubeDescription)
        {
            using (var ts = new TransactionScope())
            {
                var category = Categories.FirstOrDefault(c => c.ID == categoryId);

                if (category == null)
                {
                    throw new InvalidOperationException("Specified category does not exist.");
                }

                // Create artist if it doesn't exist
                int artistID;
                artistName = artistName.Replace(".", "");
                if (GetArtistByName(artistName) != null)
                    artistID = GetArtistByName(artistName).ARTIST_IDZ;
                else
                    artistID = CreateArtist(artistName, categoryId);

                var now = DateTime.UtcNow;

                var story = new Story
                {
                    Title = WebHelper.CreateAmper(songTitle.Trim()),
                    Description = description.Trim(),
                    youTubeDescription = youTubeDescription.Trim(),
                    CategoryID = categoryId,
                    PostedByUserName = aspnet_Users.Where(s => s.UserId == userId).SingleOrDefault().UserName,
                    PostedOn = now,
                    ARTIST_IDZ = artistID,
                    ArtistName = WebHelper.CreateAmper(artistName.Trim()),
                    YouTubeID = videoID.Trim(),
                    Status = 1
                };

                Stories.InsertOnSubmit(story);

                SubmitChanges();

                #region mp3Files

                int counterMp3 = 1;

                foreach (string mp3Url in fileUrl)
                {
                    if (mp3Url.Length < 512)
                    {
                        MP3FILE mp3FileObject = new MP3FILE
                        {
                            Story_ID = story.ID,
                            url = mp3Url,
                            IsValid = true,
                            Title = WebHelper.CreateAmper(songTitle + " - " + artistName),
                            DateCreated = DateTime.Now,
                            Count = counterMp3
                        };
                        MP3FILEs.InsertOnSubmit(mp3FileObject);
                        counterMp3++;
                    }
                }

                #endregion

                #region Tags

                if (!string.IsNullOrEmpty(tags))
                {
                    var tagsArray = tags.Split(',');

                    if (tagsArray.Length > 0)
                    {
                        var newTags = new List<Tag>();
                        var allTags = new List<Tag>();

                        for (var i = 0; i < tagsArray.Length; i++)
                        {
                            var tagName = tagsArray[i].Trim();

                            if (tagName.Length > 0)
                            {
                                if (tagName.Length > 64)
                                    tagName = tagName.Substring(0, 64);
                                var tag = Tags.FirstOrDefault(t => t.Name == tagName);

                                if (tag == null)
                                {
                                    tag = new Tag { Name = tagName };
                                    newTags.Add(tag);
                                }

                                allTags.Add(tag);
                            }
                        }

                        if (newTags.Count > 0)
                        {
                            Tags.InsertAllOnSubmit(newTags);
                            SubmitChanges();
                        }

                        if (allTags.Count > 0)
                        {
                            var storyTags = new List<StoryTag>();

                            for (var i = 0; i < allTags.Count; i++)
                            {
                                storyTags.Add(new StoryTag { StoryID = story.ID, TagID = allTags[i].ID });
                            }

                            StoryTags.InsertAllOnSubmit(storyTags);
                            SubmitChanges();
                        }
                    }
                }

                #endregion Tags

                #region Votes

                var vote = new Vote { StoryID = story.ID, UserID = userId, Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("9E755425-EE28-47A3-A235-F8F3647C163A"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("09D8939E-A743-4D77-AD15-637E2F216164"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("7F95F2B3-BC65-40A8-A801-0ED9C5E770C7"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("D13D8B0C-321F-46DC-B825-C5FCA9BBABC8"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("2EA629AC-DCEC-4F12-B953-DC274768D6ED"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                story.PublishedOn = DateTime.Now;
                #endregion Votes

                SubmitChanges();
                ts.Complete();
                return story.ID;
            }
        }

        public ARTIST GetArtistByName(string artistName)
        {
            try
            {
                return ARTISTs.SingleOrDefault(s => s.NAME == artistName);
            }
            catch
            {
                return null;
            }
        }

        public int CreateArtist(string artistName, int categoryId)
        {
            artistName = WebHelper.CreateAmper(artistName);
            int artistID;
            List<IMAGE> listaSliki = new List<IMAGE>();
            ARTIST artist = new ARTIST();

            artist = GetArtistByName(artistName);

            if (artist == null)
            {
                try
                {
                    using (var ts = new TransactionScope())
                    {
                        artist = new ARTIST();
                        artist.DateCreated = DateTime.Now;
                        artist.Category = categoryId;

                        #region Basic info

                        DISCOGZ disco = new DISCOGZ();
                        disco.API_KEY = "c09e193fa7";
                        DiscogsAPI.ResponseClasses.ArtistRequest.artist art = disco.FindArtist(artistName);
                        int counter = 0;

                        if (art != null)
                        {
                            artist.NAME = WebHelper.CutString(art.name, 149);

                            if (art.aliases != null)
                            {
                                foreach (string alias in art.aliases)
                                {
                                    artist.aliases = artist.aliases + "|" + alias;
                                    counter++;
                                    if (counter > 15)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.aliases = WebHelper.CutString(artist.aliases, 3999);
                            }

                            if (art.namevariations != null)
                            {
                                foreach (string nameVar in art.namevariations)
                                {
                                    artist.namevariations = artist.namevariations + "|" + nameVar;
                                    counter++;
                                    if (counter > 10)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.namevariations = WebHelper.CutString(artist.namevariations, 3999);
                            }

                            artist.REALNAME = WebHelper.CutString(art.realname, 100);

                            if (art.urls != null)
                            {
                                foreach (string uri in art.urls)
                                {
                                    artist.URLS = artist.URLS + "|" + uri;
                                    counter++;
                                    if (counter > 10)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.URLS = WebHelper.CutString(artist.URLS, 3999);
                            }
                        }
                        else
                        {// Create the artist if it doesn't exist in the api
                            artist.NAME = WebHelper.CutString(artistName, 149);
                        }

                        artist.DateCreated = DateTime.Now;

                        #endregion Basic Info

                        ARTISTs.InsertOnSubmit(artist);
                        SubmitChanges();
                        artistID = artist.ARTIST_IDZ;

                        #region Images

                        listaSliki = disco.GetImages(artist.NAME, artist.ARTIST_IDZ);
                        if (listaSliki.Count == 0)
                        {
                            GoogleAPI googleAPI = new GoogleAPI();
                            listaSliki = googleAPI.GetImages(artist.NAME, artist.ARTIST_IDZ);
                        }

                        IMAGEs.InsertAllOnSubmit(listaSliki);
                        SubmitChanges();

                        #endregion Images

                        #region AllMusic

                        AllMusicBin allMusicBin = AllMusicAPI.SearchRequest(artist.NAME);
                        if (allMusicBin == null)
                            SetArtistProbablyNotValidFlag(artist);
                        else
                            InsertAllMusicBin(ref allMusicBin, ref artist);

                        SubmitChanges();

                        #endregion

                        #region EchoNest

                        EchoArtistBin echoBin = EchonestAPI.SearchRequest(artist.NAME);

                        if (echoBin == null)
                            EchoNotValid(artist);
                        else
                            InsertEchoBin(ref echoBin, ref artist);

                        #endregion

                        SubmitChanges();
                        ts.Complete();
                    }
                }
                catch (Exception ex)
                {
                    throw new ApplicationException(ex.Message);
                }
            }
            else
                artistID = artist.ARTIST_IDZ;
            return artistID;
        }

        public void SetArtistProbablyNotValidFlag(ARTIST artist)
        {
            using (var ts = new TransactionScope())
            {
                if (artist == null)
                {
                    ts.Dispose();
                    throw new ApplicationException("ARTIST IS NULL");
                }
                artist.status = -1;
                SubmitChanges();
                ts.Complete();
            }
        }

        /// <summary>
        /// Grab all music bin data and insert it in database.
        /// INSERT ARTIST IN DB
        /// </summary>
        /// <param name="allMusicBin"></param>
        public void InsertAllMusicBin(ref AllMusicBin allMusicBin, ref ARTIST artist)
        {
            try
            {
                List<ARTIST_LIST> artistList = new List<ARTIST_LIST>();
                if (artist == null)
                    return;
                int counter = 1;

                #region artist

                artist.Category = allMusicBin.Category;
                artist.MiniBio = allMusicBin.MiniBio;
                artist.Born = allMusicBin.Born;
                artist.Died = allMusicBin.Died;
                artist.status = 1;

                #endregion

                #region styles

                counter = 1;
                foreach (string style in allMusicBin.Styles)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "style",
                        Value = style,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion styles

                #region moods

                counter = 1;
                foreach (string moods in allMusicBin.Moods)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "moods",
                        Value = moods,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion moods

                #region similar artists

                counter = 1;
                foreach (string similarArtists in allMusicBin.SimilarArtists)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "similarArtists",
                        Value = similarArtists,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion

                #region years active

                counter = 1;
                foreach (string yearsActive in allMusicBin.YearsActive)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "yearsActive",
                        Value = yearsActive,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion

                artist.status = 1;
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "AllMusic Inserting artist=" + artist.NAME);
            }
        }

        public void EchoNotValid(ARTIST artist)
        {
            artist.EchoStatus = -1;
            SubmitChanges();
        }

        /// <summary>
        /// Echo bin artist data inserting
        /// </summary>
        /// <param name="echoBin"></param>
        /// <param name="artist"></param>
        public void InsertEchoBin(ref EchoArtistBin echoBin, ref ARTIST artist)
        {
            try
            {

                if (artist == null)
                    return;

                #region Artist

                artist.EchoID = echoBin.EchoID;
                artist.Familiarity = echoBin.familiarity;
                artist.hotttnesss = echoBin.hotttnesss;

                #endregion

                #region Bio

                if (echoBin.Biographies != null)
                {
                    foreach (Bio bio in echoBin.Biographies)
                    {
                        ARTIST_BIO artBio = new ARTIST_BIO()
                        {
                            ARTIST_IDZ = artist.ARTIST_IDZ,
                            SiteName = WebHelper.CutString(bio.SiteName, 128),
                            SourceUrl = WebHelper.CutString(bio.SourceUrl, 128),
                            Text = WebHelper.CutString(bio.Text, 3999)
                        };
                        ARTIST_BIOs.InsertOnSubmit(artBio);
                    }
                    SubmitChanges();
                }


                #endregion

                #region Blogs

                if (echoBin.Blogs != null)
                {
                    foreach (Blog blog in echoBin.Blogs)
                    {
                        ARTIST_BLOG artBlog = new ARTIST_BLOG();
                        artBlog.ARTIST_IDZ = artist.ARTIST_IDZ;
                        artBlog.Name = WebHelper.CutString(blog.Name, 128);
                        artBlog.Summary = WebHelper.CutString(blog.Summary, 3999);
                        artBlog.Url = WebHelper.CutString(blog.Url, 128);
                        ARTIST_BLOGs.InsertOnSubmit(artBlog);
                    }
                    SubmitChanges();
                }

                #endregion

                #region Reviews

                if (echoBin.Reviews != null)
                {
                    foreach (Review review in echoBin.Reviews)
                    {
                        ARTIST_REVIEW artReview = new ARTIST_REVIEW();
                        artReview.ARTIST_IDZ = artist.ARTIST_IDZ;
                        artReview.Name = WebHelper.CutString(review.Name, 128);
                        artReview.Summary = WebHelper.CutString(review.Summary, 3999);
                        artReview.URL = WebHelper.CutString(review.Url, 128);
                        artReview.ReleaseName = WebHelper.CutString(review.ReleaseName, 128);
                        artReview.ImageURL = WebHelper.CutString(review.ImageUrl, 128);
                        ARTIST_REVIEWs.InsertOnSubmit(artReview);
                    }
                    SubmitChanges();
                }

                #endregion

                artist.EchoStatus = 1;
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "Bakldflaskdjf");
            }
        }

        public bool StoryExists(string songName, string artistName)
        {
            
                int numStories =Stories.Where(s => s.Title == songName && s.ArtistName == artistName).Count();
                if (numStories == 0)
                    return false;
                else
                    return true;
            
        }

    }
}
